package top.lshaci.learning.springboot.mybatisplus.config;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.schema.Column;

import java.util.List;

/**
 * TenantAccountLineHandler
 *
 * @author lshaci
 * @version 1.0.2
 * @since 1.0.2
 */
public class TenantAccountLineHandler implements TenantLineHandler {

    @Override
    public Expression getTenantId() {
        return new StringValue(StrUtil.blankToDefault("获取tenantId", StrUtil.EMPTY));
    }

    /**
     * 获取账套 ID 值表达式，只支持单个 ID 值
     * <p>
     *
     * @return 账套 ID 值表达式
     */
    public Expression getAccountId() {
        return new StringValue(StrUtil.blankToDefault("获取accountId", StrUtil.EMPTY));
    }

    /**
     * 获取账套字段名
     * <p>
     * 默认字段名叫: account_id
     *
     * @return 账套字段名
     */
    public String getAccountIdColumn() {
        return "account_id";
    }

    @Override
    public boolean ignoreTable(String tableName) {
        List<String> tableWhiteList = CollUtil.newArrayList();
        tableName = removeSpecialCharacter(tableName);
        return StrUtil.equalsIgnoreCase(tableName, "dual") || tableWhiteList.contains(tableName);
    }

    /**
     * 忽略插入租户字段逻辑
     *
     * @param columns 插入字段
     * @return true则忽略
     */
    public boolean ignoreInsertTenant(List<Column> columns) {
        return ignoreInsert(columns, getTenantIdColumn());
    }

    /**
     * 忽略插入账套字段逻辑
     *
     * @param columns 插入字段
     * @return true则忽略
     */
    public boolean ignoreInsertAccount(List<Column> columns) {
        return ignoreInsert(columns, getTenantIdColumn());
    }

    /**
     * 忽略插入账套、租户字段逻辑
     *
     * @param columns 插入字段
     * @return true则忽略
     */
    @Override
    public boolean ignoreInsert(List<Column> columns, String columnName) {
        return columns.stream()
                .map(Column::getColumnName)
                .map(this::removeSpecialCharacter)
                .anyMatch(i -> i.equalsIgnoreCase(columnName));
    }

    /**
     * 移除特殊字符, 并转为小写
     *
     * @param str 表名或列名
     * @return 移除特殊字符后的表名或列名
     */
    private String removeSpecialCharacter(String str) {
        return StrUtil.removeAny(str, "\"", "`").toLowerCase();
    }
}
